package com.sunbird.crm.base.aspect;

import com.sunbird.crm.base.manager.factory.AsynFactory;
import com.sunbird.crm.base.manager.factory.AsynManager;
import com.sunbird.crm.base.utils.ShiroUtils;
import com.sunbird.crm.entity.sys.TLog;
import com.sunbird.crm.entity.sys.TUser;
import com.sunbird.crm.servce.LogService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Date;

/**
 * @ClassName LogAspect
 * @Descriptiom TODO
 * @Author Sunbird
 * @Date 2019/9/4 21:41
 * @Version 1.0
 **/
@Aspect
@Component
public class LogAspect {

   private Logger logger = LoggerFactory.getLogger(LogAspect.class);

   @Autowired
   private LogService logService;

   @Pointcut("@annotation(com.sunbird.crm.base.aspect.AopLog)")
   public void controllerAspect(){}


   @Before("controllerAspect()")
   public void logBeforeController(JoinPoint joinPoint){
       RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();//这个RequestContextHolder是Springmvc提供来获得请求的东西
       HttpServletRequest request = ((ServletRequestAttributes)requestAttributes).getRequest();
       Subject subject =SecurityUtils.getSubject();
       TUser user = ShiroUtils.getSysUser();
       Session session=subject.getSession();
       session.getAttribute("userName");
//       新建日志对象
       TLog log = new TLog();
       log.setRequestIp(request.getRequestURI());
       log.setRequsetMethod(request.getMethod());
       log.setRequestIp(request.getRemoteAddr());
       log.setCreateBy(user.getUserName());
       log.setCreateDate(new Date());
       log.setLogTitle(joinPoint.getSignature().getDeclaringTypeName());
       try {
          AopLog logAspect = getAnnotationLog(joinPoint);
           log.setLogTitle(logAspect.value());
       } catch (Exception e) {
           e.printStackTrace();
       }
       AsynManager.me().execute(AsynFactory.recordOper(log));
       // 记录下请求内容
       logger.info("################URL : " + request.getRequestURL().toString());
       logger.info("################URL : " + subject.getPrincipals().getPrimaryPrincipal().toString());
       logger.info("################HTTP_METHOD : " + request.getMethod());
       logger.info("################IP : " + request.getRemoteAddr());
       logger.info("################THE ARGS OF THE CONTROLLER : " + Arrays.toString(joinPoint.getArgs()));
       //下面这个getSignature().getDeclaringTypeName()是获取包+类名的   然后后面的joinPoint.getSignature.getName()获取了方法名
       logger.info("################CLASS_METHOD : " + joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName());
       //logger.info("################TARGET: " + joinPoint.getTarget());//返回的是需要加强的目标类的对象
       //logger.info("################THIS: " + joinPoint.getThis());//返回的是经过加强后的代理类的对象
   }



    /**
     * 是否存在注解，如果存在就获取
     */
    private AopLog getAnnotationLog(JoinPoint joinPoint) throws Exception
    {
        Signature signature = joinPoint.getSignature();
        MethodSignature methodSignature = (MethodSignature) signature;
        Method method = methodSignature.getMethod();
        if (method != null)
        {
            return method.getAnnotation(AopLog.class);
        }
        return null;
    }
}
